<?php
namespace app\service\message\receive\normal;

use app\model\Plug;
use app\service\Base;
use app\yhUtil\type\Text;
use app\yhUtil\YhApi;
use GuzzleHttp\Client;

class File extends Base {
    public function run() {
        $content = $this->message['content'];
        $file = $content['fileName'];
        $plug = Plug::where(["plug_name" => $content['fileName']])->findOrEmpty();
        if(!$plug->isEmpty()){
            return $this->responseText("该插件[{$content['fileName']}]已存在");
        }
        $fileInfo = explode('.', $file);
        $fileType = end($fileInfo);
        switch($fileType){
            case "php":
                $plugPath = app_path('plugs');
                if(!is_dir($plugPath)) mkdir($plugPath, 0755, true);
                // 构造保存路径
                $targetFile = $plugPath . $content['fileName'];
                try {
                    // 使用已有的getPlug方法下载文件
                    $fileContent = $this->getPlug($content['fileUrl']); // 假设有下载URL参数

                    // 保存文件内容
                    if(file_put_contents($targetFile, $fileContent)){
                        $this->checkPlugClass($targetFile);
                    }
                } catch (\Exception $e) {
                    // 处理下载/保存异常
                    unlink($targetFile); // 清理失败文件
                }
                break;
        }
    }

    public function getPlug($file){
        $c = new Client(['base_uri'=> 'https://chat-file.jwznb.com/']);
        $header = [
            'Referer' => 'http://myapp.jwznb.com/'
        ];
        $res = $c->request('GET', $file, ['headers' => $header]);
        $fileContent = $res->getBody()->getContents();
        return $fileContent;
    }

    private function checkPlugClass($filePath){
        $className = $this->getClassNameFromFile($filePath);

        if(!class_exists($className)){
            require_once $filePath; // 动态加载类文件
        }
        
        try {
            $reflection = new \ReflectionClass($className);
            if(!$reflection->isSubclassOf('app\plugs\Base')){
                unlink($filePath); // 删除不符合要求的文件
                throw new \Exception("插件必须继承 Base 类");
            }
            $obj = new $className($this);
            $info = $obj->getInfo();
            if(!$info){
                unlink($filePath);
                throw new \Exception("插件信息错误");
            }
            Plug::create([
                'class_path'    => $className,
                'plug_name'     => $info['name'],
                'plug_version'  => $info['version'],
                'author'        => $info['author'],
                'desc'     => $info['desc'],
            ]);
            trace($info, 'plug.info');
            return $this->responseText("插件[{$info['name']}]安装成功: \"{$info['desc']}\" by ({$info['author']})");
        } catch (\Exception $e) {
            trace("{$e->getFile()}[{$e->getLine()}]: {$e->getMessage()}", 'error');
            // 处理异常
        }
    }
    
    // 从文件解析类名
    private function getClassNameFromFile($filePath){
        $content = file_get_contents($filePath);
        preg_match('/namespace\s+(.+?);.*?class\s+(\w+)/s', $content, $matches);
        return $matches[1].'\\'.$matches[2];
    }
}